package com.archgeek.rpc.proxy.custom;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/**
 * @author pizhihui
 * @date 2024-05-22 23:14
 */
public class MyClassLoader extends ClassLoader {

    private String baseDir;

    public MyClassLoader() {
        this.baseDir = MyClassLoader.class.getResource("").getPath();
    }

//    @Override
//    protected Class<?> findClass(String name) throws ClassNotFoundException {
//
//        String className = MyClassLoader.class.getPackage().getName() + "." + name;
//
//        if (null == baseDir) {
//            throw new ClassNotFoundException();
//        }
//
//        File file = new File(baseDir, name + ".class");
//        if (!file.exists()) {
//            throw new ClassNotFoundException();
//
//        }
//
//        try (
//                FileInputStream fi = new FileInputStream(file);
//                ByteArrayOutputStream bao = new ByteArrayOutputStream();
//        ) {
//            byte[] buffer = new byte[1024];
//            int len;
//            while ((len = fi.read(buffer)) != -1) {
//                bao.write(buffer, 0, len);
//            }
//            return defineClass(className, bao.toByteArray(), 0, bao.size());
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//
//
//        return null;
//    }

    /**
     * 通过类名称加载类字节码文件到JVM中
     * @param name 类名
     * @return 类的Class独享
     * @throws ClassNotFoundException
     */
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        // 获取类名
        String className = MyClassLoader.class.getPackage().getName()+"."+name;
        if(null == baseDir) {
            throw new ClassNotFoundException();
        }

        // 获取类文件
        File file = new File(baseDir,name+".class");
        if(!file.exists()){
            throw new ClassNotFoundException();
        }

        // 将类文件转换为字节数组
        try(
                FileInputStream in = new FileInputStream(file);
                ByteArrayOutputStream out = new ByteArrayOutputStream();
        ){
            byte[] buffer = new byte[1024];
            int len;
            while ((len = in.read(buffer))!=-1){
                out.write(buffer,0,len);
            }

            // 调用父类方法生成class实例
            return defineClass(className,out.toByteArray(),0,out.size());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}
